package com.zzl.admin.service.sceKill.impl;

import com.zzl.admin.exception.CommonException;
import com.zzl.admin.service.redisLock.RedisLock;
import com.zzl.admin.service.sceKill.SecKillService;
import com.zzl.admin.utils.KeyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * Description：秒杀活动服务接口实现类
 * Created by 朱正磊 on 2019-05-11 22:03
 */
@Service
public class SecKillServiceImpl implements SecKillService {

    private static final int TIMEOUT = 10 * 1000;//超时时间 10s

    @Autowired
    private RedisLock redisLock;

    /**
     * 国庆活动，皮蛋粥特价，限量100000份
     */
    static Map<String, Integer> products;//商品库存（总库存）
    static Map<String, Integer> stock;//库存（变化库存）
    static Map<String, String> orders;//订单

    static {
        /**
         * 模拟多张表，商品信息表，库存表，秒杀成功订单表
         */
        products = new HashMap<>();
        stock = new HashMap<>();
        orders = new HashMap<>();
        products.put("123456", 100000);
        stock.put("123456", 100000);
    }

    /**
     * description：查询秒杀商品信息
     * user 朱正磊
     * time 2019-05-11 23:37
     * @param productId 商品ID
     * @return 返回秒杀商品信息
     */
    private String queryMap(String productId) {
        return "国庆活动，皮蛋粥特价，限量" + products.get(productId) + "份"
                + "，还剩：" + stock.get(productId) + "份"
                + "，该商品成功下单用户数目：" + orders.size() + "人";
    }

    /**
     * description：查询秒杀商品信息
     * user 朱正磊
     * time 2019-05-11 23:36
     * @param productId 商品ID
     * @return 返回秒杀商品信息
     */
    @Override
    public String querySecKillProductInfo(String productId) {
        return this.queryMap(productId);
    }

    /**
     * description：模拟多线程秒杀商品
     * user 朱正磊
     * time 2019-05-11 22:12
     * @param productId 商品ID
     */
    @Override
    public void orderProductMockDiffUser(String productId) {
        //一、加锁
        long time = System.currentTimeMillis() + TIMEOUT;//值
        if (!redisLock.lock(productId, String.valueOf(time))) {//如果为true表示加锁失败
            throw new CommonException(100, "哎呦喂，人也太多了吧，请换个姿势再试试~~~");
        }

        //业务逻辑代码
        //1、查询该商品的库存，如果为0则表示该活动已经结束
        int stockNum = stock.get(productId);//获取当前商品的库存
        if (stockNum == 0) {//如果库存为0，表示当前商品已经卖完
            throw new CommonException(101, "活动已结束！");
        } else {
            //2、下单（模拟不同用户，根据openid不同进行模拟）
            orders.put(KeyUtil.genUniqueKey(), productId);
            //3、减库存
            stockNum = stockNum - 1;
            try {
                Thread.sleep(100);//线程睡眠0.1s
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            stock.put(productId, stockNum);//更新库存
        }

        //二、解锁
        redisLock.unlock(productId, String.valueOf(time));
    }

}
